use mysql::Pool;
use mysql::prelude::FromRow;
use mysql::Row;
use mysql::FromRowError;

use serde::{Deserialize, Serialize};
use tide::{response, Context, EndpointResult};
use crate::common::Response;


#[derive(Serialize, Deserialize, Clone)]
struct OdrQuota{
    id: String,
    code: u32,
    year: u32,
    quarter: u32,
    month: u32,
    ym: u32,
    idata: u32,
    fdata: f32,
    edata: Option<String>
}

impl FromRow for OdrQuota{
    fn from_row(row: Row) -> OdrQuota{
        OdrQuota{
            id: row.get(0).unwrap(),
            code: row.get(1).unwrap(),
            year: row.get(2).unwrap(),
            quarter: row.get(3).unwrap(),
            month: row.get(4).unwrap(),
            ym: row.get(5).unwrap(),
            idata: row.get(6).unwrap(),
            fdata: row.get(7).unwrap(),
            edata: row.get(8)
        }
    }

    fn from_row_opt(row: Row) -> Result<OdrQuota, FromRowError>{
        let quota = OdrQuota{
            id: row.get(0).unwrap(),
            code: row.get(1).unwrap(),
            year: row.get(2).unwrap(),
            quarter: row.get(3).unwrap(),
            month: row.get(4).unwrap(),
            ym: row.get(5).unwrap(),
            idata: row.get(6).unwrap(),
            fdata: row.get(7).unwrap(),
            edata: row.get(8)
        };
        Ok(quota)
    }
}


#[derive(Serialize, Deserialize, Clone)]
struct Message {
    author: Option<String>,
    contents: String,
}

#[allow(dead_code)]
async fn hello(ctx: Context<Pool>) -> EndpointResult {
    let sql = "select quota_id, quota_code, report_year, report_quarter, report_month, `year_month`, integer_data, float_data, extra_data
     from odr_quota_data where quota_code = :code and report_year = :year";
    let param = params!{"code" => 104001, "year" => 2019};

    let vector: Vec<OdrQuota> = ctx.state().prep_exec(sql, param)
        .map(|result| {
            result.map(|x| x.unwrap()).map(|row|{
                let item: OdrQuota = mysql::from_row(row);
                item
            }).collect()
        }).unwrap();
    Ok(response::json(Response::ok().data(vector)))
}


#[test]
pub fn mysql_test(){
    use tide::App;
    
    let user = "root";
    let addr = "118.190.202.221";
    let port = 3306;
    let mut builder = mysql::OptsBuilder::default();
    builder.user(Some(user))
        .pass(Some("CloudseaDev666"))
        .ip_or_hostname(Some(addr))
        .db_name(Some("NCZXYY_ODR_TEST"))
        .tcp_port(port);
    let pool = Pool::new_manual(2, 4, builder).unwrap();

    let mut app = App::with_state(pool);
    app.at("/hello").get(hello);
    app.run("0.0.0.0:8020").unwrap();
}